package com.fingard.dsp.bank.directbank.yeepay01;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.cfca.util.pki.api.CertUtil;
import com.cfca.util.pki.api.KeyUtil;
import com.cfca.util.pki.api.SignatureUtil;
import com.cfca.util.pki.cert.X509Cert;
import com.cfca.util.pki.cipher.JCrypto;
import com.cfca.util.pki.cipher.JKey;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.WebRequest;
import com.fingard.text.StringHelper;
import com.fingard.util.CallbackUtils;
import com.fingard.util.Digest;
import com.fingard.xml.XmlTextWriter;

public class YEEPAY01Base extends DirectBase{
//	private Map<String,String>	pfxNameMap = new HashMap<String,String>();
//	private Map<String,String>	pfxPassMap = new HashMap<String,String>();
	protected void writeCommonHeader(XmlTextWriter xmlWriter,YEEPAY01Header header) throws Exception {
		xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"GBK\"?>");
		xmlWriter.writeStartElement("date");
		xmlWriter.writeElementString("cmd",header.cmd);
		xmlWriter.writeElementString("version",header.version);
		xmlWriter.writeElementString("group_Id",header.group_Id);
		xmlWriter.writeElementString("mer_Id",header.mer_Id);
		xmlWriter.writeElementString("product",header.product);
	}

	protected String getCharset() {
		return getBankConfig().getCharset("GBK");
	}

	protected String[] sendToBank(String p_reqStr) throws Exception {
		WriteBankLogStep2(p_reqStr);

		// 发送给银行
		String[] retStr = new String[] { "", "" };
		String tmpAddrLogin = bankFront.serverURL;
		WriteBankLogLn2("银行的地址" + tmpAddrLogin);
		WebRequest loginWebRequest = new WebRequest(tmpAddrLogin);
		loginWebRequest.setConnectTimeout(10000);
		loginWebRequest.setRequestProperty("User-Agent", "API");
		byte[] tmpLoginBytes = p_reqStr.getBytes(getCharset());
		retStr = loginWebRequest.upload(tmpLoginBytes, getCharset());
		WriteBankLogStep3(retStr[1]);
		return retStr;
	}
	
	protected String getProvince(String cityStr){
		if(StringHelper.isNullOrEmpty(cityStr)){
			return null;
		}
		int length=cityStr.length();
		String province=cityStr.substring(0, 2);
		for(int i=0;i<length-2;i++){
			province+="0";
		}
		return province;
	} 
	
	/**
	 * MD5+证书签名
	 */
	public String buildCertSign(String hmacStr, ActSetItem actItem) {
		// 下面用数字证书进行签名
		String signMessage = "";
		com.cfca.util.pki.cipher.Session tempsession = null;
		String ALGORITHM = SignatureUtil.SHA1_RSA;
		JCrypto jcrypto = null;
		if (tempsession == null) {
			try {
				// 初始化加密库，获得会话session
				// 多线程的应用可以共享一个session,不需要重复,只需初始化一次
				// 初始化加密库并获得session。
				// 系统退出后要jcrypto.finalize()，释放加密库
				jcrypto = JCrypto.getInstance();
				jcrypto.initialize(JCrypto.JSOFT_LIB, null);
				tempsession = jcrypto.openSession(JCrypto.JSOFT_LIB);
			} catch (Exception ex) {
				System.out.println(ex);
			}
		}
		// String sysPath="D:\\workspace\\yeePayProxy\\WebContent\\";
		String sysPath = this.getClass().getResource("").getPath().split(
				"WEB-INF")[0];
		try {
			JKey jkey = KeyUtil.getPriKey(actItem.ownKeyStorePath, actItem.ownKeyPassword);
			X509Cert cert = CertUtil.getCert(actItem.ownKeyStorePath, actItem.ownKeyPassword);
			X509Cert[] cs = new X509Cert[1];
			cs[0] = cert;

			SignatureUtil signUtil = null;

			// 第二步:对请求的串进行MD5对数据进行签名
			String yphs = Digest.hmacSign(hmacStr);
			signUtil = new SignatureUtil();
			byte[] b64SignData;
			// 第三步:对MD5签名之后数据调用CFCA提供的api方法用商户自己的数字证书进行签名
			b64SignData = signUtil.p7SignMessage(true, yphs.getBytes(),
					ALGORITHM, jkey, cs, tempsession);
			if (jcrypto != null) {
				jcrypto.finalize(com.cfca.util.pki.cipher.JCrypto.JSOFT_LIB,
						null);
			}
			signMessage = new String(b64SignData, "UTF-8");
		} catch (Exception e) {
			System.out.println(e);
		}
		System.out.println("经过md5和数字证书签名之后的数据为---||" + signMessage + "||");
		return signMessage;
	}
	
	
	protected String sendData(String xml) {
		System.out.println("发送报文:" + xml);
		Document document = null;
		SignatureUtil signUtil = new SignatureUtil();
		com.cfca.util.pki.cipher.Session tempsession = null;
		JCrypto jcrypto = null;
		if (tempsession == null) {
			try {
				// 初始化加密库，获得会话session
				// 多线程的应用可以共享一个session,不需要重复,只需初始化一次
				// 初始化加密库并获得session。
				// 系统退出后要jcrypto.finalize()，释放加密库
				jcrypto = JCrypto.getInstance();
				jcrypto.initialize(JCrypto.JSOFT_LIB, null);
				tempsession = jcrypto.openSession(JCrypto.JSOFT_LIB);
			} catch (Exception ex) {
				System.out.println(ex);
				return null;
			}
		}
		// 第四步:发送https请求
		String responseMsg = CallbackUtils.httpRequest("http://10.2.252.4/app-merchant-proxy/transferController.action", xml, "POST",
				"gbk", "text/xml ;charset=gbk", false);

		// out.println(responseMsg);
		System.out.println("服务器响应xml报文:" + responseMsg);

		try {
			document = DocumentHelper.parseText(responseMsg);

			Element rootEle = document.getRootElement();
			String cmdValue = rootEle.elementText("hmac");

			// 第五步:对服务器响应报文进行验证签名
			if (cmdValue != null) {
				boolean flag = signUtil.p7VerifySignMessage(
						cmdValue.getBytes(), tempsession);
				if (flag) {
					
					return responseMsg;
//					log.info("验签成功");
//					log.info("验签获得的MD5签名数据为----"
//							+ new String(signUtil.getSignedContent()));
//					log.info("验签获得的证书dn为----"
//							+ new String(signUtil.getSigerCert()[0]
//									.getSubject()));
					// 第六步.将验签出来的结果数据与自己针对响应数据做MD5签名之后的数据进行比较是否相等
					// 第七步:判断该证书DN是否为易宝
					// 第八步:.......加上自己的业务逻辑
				} else {
					System.out.println("验签失败....");
					return null;
				}
			}
		} catch (Exception e) {
			System.out.println(e);
			return null;
		}
		return responseMsg;
	}
}
